"""
分类服务

统一管理和协调各种AI分类器。
"""

import asyncio
from typing import Dict, List, Any, Optional
from datetime import datetime
import logging

from src.core.di import Injectable, Inject, Service
from src.modules.scanners.base import FileInfo
from src.modules.classifiers.base import AIClassifier, ClassificationResult, classifier_registry
from src.modules.classifiers.gemini_classifier import GeminiVideoClassifier
from src.modules.classifiers.hybrid_classifier import HybridClassifier
from src.modules.classifiers.advanced_ai_classifier import AdvancedAIClassifier
from src.modules.classifiers.performance_evaluator import ClassificationPerformanceEvaluator


@Service("classification_service")
class ClassificationService:
    """
    分类服务
    
    统一管理和协调各种AI分类器，提供高级分类功能。
    """
    
    def __init__(self,
                 gemini_classifier: GeminiVideoClassifier = Inject(GeminiVideoClassifier),
                 hybrid_classifier: HybridClassifier = Inject(HybridClassifier),
                 advanced_classifier: AdvancedAIClassifier = Inject(AdvancedAIClassifier),
                 performance_evaluator: ClassificationPerformanceEvaluator = Inject(ClassificationPerformanceEvaluator),
                 config: Dict[str, Any] = Inject("config"),
                 logger: logging.Logger = Inject("logger")):
        
        self.gemini_classifier = gemini_classifier
        self.hybrid_classifier = hybrid_classifier
        self.advanced_classifier = advanced_classifier
        self.performance_evaluator = performance_evaluator
        self.config = config
        self.logger = logger
        
        # 服务配置
        self.service_config = config.get("classification_service", {})
        self.default_classifier = self.service_config.get("default_classifier", "hybrid")
        self.enable_performance_tracking = self.service_config.get("enable_performance_tracking", True)
        
        # 注册分类器
        self._register_classifiers()
        
        # 性能统计
        self.performance_stats = {
            "total_classifications": 0,
            "successful_classifications": 0,
            "classifier_usage": {},
            "average_processing_time": 0.0,
            "start_time": datetime.now()
        }
    
    def _register_classifiers(self) -> None:
        """注册所有可用的分类器"""
        try:
            classifier_registry.register("gemini", self.gemini_classifier)
            classifier_registry.register("hybrid", self.hybrid_classifier)
            classifier_registry.register("advanced", self.advanced_classifier)
            
            self.logger.info("分类器注册完成")
            
        except Exception as e:
            self.logger.error(f"分类器注册失败: {e}")
    
    async def classify_file(self, 
                          file_info: FileInfo, 
                          classifier_name: str = None,
                          **kwargs) -> ClassificationResult:
        """
        分类单个文件
        
        Args:
            file_info: 文件信息
            classifier_name: 指定的分类器名称
            **kwargs: 其他参数
        
        Returns:
            分类结果
        """
        start_time = datetime.now()
        
        # 选择分类器
        classifier_name = classifier_name or self.default_classifier
        classifier = classifier_registry.get(classifier_name)
        
        if not classifier:
            available_classifiers = classifier_registry.get_available_classifiers()
            return ClassificationResult(
                success=False,
                error=f"分类器 '{classifier_name}' 不可用。可用分类器: {available_classifiers}",
                classifier_type="classification_service",
                timestamp=start_time
            )
        
        try:
            self.logger.info(f"使用分类器 '{classifier_name}' 分类文件: {file_info.name}")
            
            # 执行分类
            result = await classifier.classify(file_info, **kwargs)
            
            # 更新性能统计
            if self.enable_performance_tracking:
                self._update_performance_stats(classifier_name, result, start_time)
            
            return result
            
        except Exception as e:
            error_msg = f"分类失败: {e}"
            self.logger.error(error_msg)
            
            return ClassificationResult(
                success=False,
                error=error_msg,
                classifier_type=classifier_name,
                processing_time=(datetime.now() - start_time).total_seconds(),
                timestamp=start_time
            )
    
    async def batch_classify_files(self, 
                                 file_infos: List[FileInfo],
                                 classifier_name: str = None,
                                 max_concurrent: int = 5,
                                 **kwargs) -> List[ClassificationResult]:
        """
        批量分类文件
        
        Args:
            file_infos: 文件信息列表
            classifier_name: 指定的分类器名称
            max_concurrent: 最大并发数
            **kwargs: 其他参数
        
        Returns:
            分类结果列表
        """
        self.logger.info(f"开始批量分类 {len(file_infos)} 个文件")
        
        # 控制并发数
        semaphore = asyncio.Semaphore(max_concurrent)
        
        async def classify_single(file_info: FileInfo):
            async with semaphore:
                return await self.classify_file(file_info, classifier_name, **kwargs)
        
        # 创建并发任务
        tasks = [classify_single(file_info) for file_info in file_infos]
        
        # 等待所有任务完成
        results = await asyncio.gather(*tasks, return_exceptions=True)
        
        # 处理异常结果
        final_results = []
        for i, result in enumerate(results):
            if isinstance(result, Exception):
                error_result = ClassificationResult(
                    success=False,
                    error=str(result),
                    classifier_type=classifier_name or self.default_classifier,
                    timestamp=datetime.now()
                )
                final_results.append(error_result)
            else:
                final_results.append(result)
        
        success_count = len([r for r in final_results if r.success])
        self.logger.info(f"批量分类完成: 成功 {success_count}/{len(file_infos)}")
        
        return final_results
    
    async def auto_select_classifier(self, file_info: FileInfo) -> str:
        """
        自动选择最适合的分类器
        
        Args:
            file_info: 文件信息
        
        Returns:
            推荐的分类器名称
        """
        # 获取支持该文件类型的分类器
        file_type = file_info.file_type.value
        suitable_classifiers = classifier_registry.get_classifiers_for_file_type(file_type)
        
        if not suitable_classifiers:
            return self.default_classifier
        
        # 根据文件特征选择分类器
        file_size_mb = file_info.size / (1024 * 1024)
        
        # 大文件使用更快的分类器
        if file_size_mb > 100:
            if "gemini" in suitable_classifiers:
                return "gemini"
            elif "hybrid" in suitable_classifiers:
                return "hybrid"
        
        # 小文件可以使用高级分类器
        elif file_size_mb < 10:
            if "advanced" in suitable_classifiers:
                return "advanced"
        
        # 默认使用混合分类器
        if "hybrid" in suitable_classifiers:
            return "hybrid"
        
        return suitable_classifiers[0] if suitable_classifiers else self.default_classifier
    
    async def classify_with_auto_selection(self, file_info: FileInfo, **kwargs) -> ClassificationResult:
        """
        使用自动选择的分类器进行分类
        
        Args:
            file_info: 文件信息
            **kwargs: 其他参数
        
        Returns:
            分类结果
        """
        classifier_name = await self.auto_select_classifier(file_info)
        self.logger.info(f"自动选择分类器: {classifier_name} for {file_info.name}")
        
        return await self.classify_file(file_info, classifier_name, **kwargs)
    
    async def evaluate_classifiers(self, 
                                 test_files: List[FileInfo],
                                 ground_truth: Dict[str, Any] = None,
                                 **kwargs) -> Dict[str, Any]:
        """
        评估所有可用分类器的性能
        
        Args:
            test_files: 测试文件列表
            ground_truth: 真实标签
            **kwargs: 其他参数
        
        Returns:
            评估结果
        """
        self.logger.info("开始评估所有分类器性能")
        
        # 获取所有可用分类器
        available_classifiers = []
        for name in classifier_registry.get_available_classifiers():
            classifier = classifier_registry.get(name)
            if classifier:
                available_classifiers.append(classifier)
        
        if not available_classifiers:
            return {"error": "没有可用的分类器进行评估"}
        
        # 使用性能评估器进行评估
        evaluation_result = await self.performance_evaluator.compare_classifiers(
            available_classifiers, test_files, ground_truth=ground_truth, **kwargs
        )
        
        return evaluation_result
    
    def _update_performance_stats(self, 
                                classifier_name: str, 
                                result: ClassificationResult, 
                                start_time: datetime) -> None:
        """更新性能统计"""
        try:
            self.performance_stats["total_classifications"] += 1
            
            if result.success:
                self.performance_stats["successful_classifications"] += 1
            
            # 更新分类器使用统计
            if classifier_name not in self.performance_stats["classifier_usage"]:
                self.performance_stats["classifier_usage"][classifier_name] = 0
            self.performance_stats["classifier_usage"][classifier_name] += 1
            
            # 更新平均处理时间
            processing_time = result.processing_time or (datetime.now() - start_time).total_seconds()
            total_time = self.performance_stats["average_processing_time"] * (self.performance_stats["total_classifications"] - 1)
            self.performance_stats["average_processing_time"] = (total_time + processing_time) / self.performance_stats["total_classifications"]
            
        except Exception as e:
            self.logger.error(f"更新性能统计失败: {e}")
    
    def get_performance_stats(self) -> Dict[str, Any]:
        """获取性能统计信息"""
        stats = self.performance_stats.copy()
        
        # 计算运行时间
        runtime = (datetime.now() - stats["start_time"]).total_seconds()
        stats["runtime_seconds"] = runtime
        
        # 计算成功率
        if stats["total_classifications"] > 0:
            stats["success_rate"] = stats["successful_classifications"] / stats["total_classifications"]
        else:
            stats["success_rate"] = 0.0
        
        # 计算吞吐量
        if runtime > 0:
            stats["throughput"] = stats["total_classifications"] / runtime
        else:
            stats["throughput"] = 0.0
        
        return stats
    
    def get_available_classifiers(self) -> Dict[str, Dict[str, Any]]:
        """获取所有可用分类器的信息"""
        classifiers_info = {}
        
        for name in classifier_registry.list_classifiers():
            classifier = classifier_registry.get(name)
            if classifier:
                classifiers_info[name] = {
                    "name": classifier.name,
                    "version": classifier.version,
                    "supported_file_types": classifier.supported_file_types,
                    "is_available": classifier.is_available(),
                    "metadata": classifier.get_metadata()
                }
        
        return classifiers_info
    
    async def get_classification_recommendations(self, file_info: FileInfo) -> Dict[str, Any]:
        """
        获取分类建议
        
        Args:
            file_info: 文件信息
        
        Returns:
            分类建议
        """
        recommendations = {
            "file_info": file_info.to_dict(),
            "recommended_classifier": await self.auto_select_classifier(file_info),
            "available_classifiers": [],
            "classification_strategy": "auto"
        }
        
        # 获取支持该文件类型的分类器
        file_type = file_info.file_type.value
        suitable_classifiers = classifier_registry.get_classifiers_for_file_type(file_type)
        
        for classifier_name in suitable_classifiers:
            classifier = classifier_registry.get(classifier_name)
            if classifier and classifier.is_available():
                recommendations["available_classifiers"].append({
                    "name": classifier_name,
                    "version": classifier.version,
                    "estimated_processing_time": self._estimate_processing_time(classifier_name, file_info),
                    "confidence_expectation": self._estimate_confidence(classifier_name, file_info)
                })
        
        return recommendations
    
    def _estimate_processing_time(self, classifier_name: str, file_info: FileInfo) -> float:
        """估算处理时间"""
        # 基于文件大小和分类器类型的简单估算
        file_size_mb = file_info.size / (1024 * 1024)
        
        base_times = {
            "gemini": 2.0,      # Gemini API调用较慢
            "hybrid": 1.5,      # 混合分类器中等
            "advanced": 3.0     # 高级分类器最慢但最准确
        }
        
        base_time = base_times.get(classifier_name, 1.0)
        
        # 文件大小影响因子
        size_factor = 1.0 + (file_size_mb / 100.0)  # 每100MB增加1倍时间
        
        return base_time * size_factor
    
    def _estimate_confidence(self, classifier_name: str, file_info: FileInfo) -> float:
        """估算置信度"""
        # 基于分类器类型的置信度估算
        confidence_estimates = {
            "gemini": 0.75,     # Gemini通常有较高置信度
            "hybrid": 0.80,     # 混合分类器结合多种方法
            "advanced": 0.85    # 高级分类器最准确
        }
        
        return confidence_estimates.get(classifier_name, 0.70)
